package com.gun0912.tedbottompicker;

import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialogFragment;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.gun0912.tedbottompicker.adapter.ImageGalleryAdapter;
import com.huanglejing.mylibrary.R;
import com.tbruyelle.rxpermissions.RxPermissions;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import gun0912.tedbottompicker.TransparentBarBottomSheetDialog;
import rx.Subscriber;

public class TedBottomPicker extends BottomSheetDialogFragment {

    public static final String TAG = "ted";
    static final int REQ_CODE_CAMERA = 1;
    static final int REQ_CODE_GALLERY = 2;
    ImageGalleryAdapter imageGalleryAdapter;
    Builder builder;
    TextView tv_title;
    TextView confirm;
    ArrayList<Uri> picData = new ArrayList<>();
    private RecyclerView rc_gallery;
    private boolean isImage = false;
    private int oldImageCount = 0;
    private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {


        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {

            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                dismiss();
            }

        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {

        }
    };
    private Uri cameraImageUri;

    public int getOldImageCount() {
        return oldImageCount;
    }

    public void setOldImageCount(int oldImageCount) {
        this.oldImageCount = oldImageCount;
    }

    synchronized public void show(FragmentManager fragmentManager) {
        if (!this.isAdded()) {
            FragmentTransaction ft = fragmentManager.beginTransaction();
            ft.add(this, getTag());
            ft.commitAllowingStateLoss();
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new TransparentBarBottomSheetDialog(getActivity(), null);
    }


    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View contentView = View.inflate(getContext(), R.layout.tedbottompicker_content_view, null);
        dialog.setContentView(contentView);
        CoordinatorLayout.LayoutParams layoutParams =
                (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
        CoordinatorLayout.Behavior behavior = layoutParams.getBehavior();
        if (behavior != null && behavior instanceof BottomSheetBehavior) {
            ((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
            if (builder != null && builder.peekHeight > 0) {
                // ((BottomSheetBehavior) behavior).setPeekHeight(1500);
                ((BottomSheetBehavior) behavior).setPeekHeight(builder.peekHeight);
            }

        }

        rc_gallery = (RecyclerView) contentView.findViewById(R.id.rc_gallery);
        setRecyclerView();

        tv_title = (TextView) contentView.findViewById(R.id.tv_title);
        confirm = (TextView) contentView.findViewById(R.id.bt_confirm_image);
        if (builder != null && builder.isSingle()) {
            confirm.setVisibility(View.GONE);
        } else {
            confirm.setVisibility(View.VISIBLE);
        }
        confirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (builder != null)
                    // builder.onImageSelectedListener.onImageSelected(uri);
                    builder.onImageSelectedListener.onImageSelected(picData);
                dismiss();
            }
        });
        setTitle();
    }


    private void setRecyclerView() {

        GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
        rc_gallery.setLayoutManager(gridLayoutManager);

        if (builder != null) {
            rc_gallery.addItemDecoration(new GridSpacingItemDecoration(gridLayoutManager.getSpanCount(), builder.spacing, false));
            picData.clear();
            imageGalleryAdapter = new ImageGalleryAdapter(
                    getActivity()
                    , builder);
            rc_gallery.setAdapter(imageGalleryAdapter);
            imageGalleryAdapter.setOnItemClickListener(new ImageGalleryAdapter.OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    ImageGalleryAdapter.PickerTile pickerTile = imageGalleryAdapter.getItem(position);

                    switch (pickerTile.getTileType()) {
                        case ImageGalleryAdapter.PickerTile.CAMERA:
                            isImage = false;
                            startCameraIntent();
                            break;
                        case ImageGalleryAdapter.PickerTile.GALLERY:
                            isImage = false;
                            startGalleryIntent();
                            break;
                        case ImageGalleryAdapter.PickerTile.IMAGE:
                            isImage = true;
                            if (picData.size() >= builder.getMaxSelect() - oldImageCount && !pickerTile.isSelect()) {
                                Toast.makeText(getContext(), "您最多可以选" + (builder.getMaxSelect() - oldImageCount) + "张", Toast.LENGTH_LONG).show();
                                return;
                            } else {
                                pickerTile.setSelect(!pickerTile.isSelect());
                                imageGalleryAdapter.notifyItemChanged(position);
                                complete(pickerTile.getImageUri());
                            }
                            break;

                        default:
                            errorMessage();
                    }


                }
            });
        }

    }

    private void setTitle() {

        if (builder != null && !builder.showTitle) {
            tv_title.setVisibility(View.GONE);
            return;
        }

        if (builder != null && !TextUtils.isEmpty(builder.title)) {
            tv_title.setText(builder.title);
        }

        if (builder != null && builder.titleBackgroundResId > 0) {
            tv_title.setBackgroundResource(builder.titleBackgroundResId);
        }

    }


    private void complete(Uri uri) {
        if (uri.getScheme().contains("content")) {
            //KLog.d("from content provider");
            String filePath;
            String[] filePathColumn = {MediaStore.MediaColumns.DATA};

            Cursor cursor = getActivity().getContentResolver().query(uri, filePathColumn, null, null, null);
//      也可用下面的方法拿到cursor
//      Cursor cursor = this.context.managedQuery(selectedVideoUri, filePathColumn, null, null, null);

            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            filePath = cursor.getString(columnIndex);
            cursor.close();
            uri = Uri.fromFile(new File(filePath));
            //KLog.d("transform :" + uri);
        }
        if (picData.contains(uri)) {
            picData.remove(uri);
        } else {
            if (builder.getMaxSelect() - oldImageCount > picData.size()) {
                picData.add(uri);
            } else {
                Toast.makeText(getContext(), "您最多可以选" + (builder.getMaxSelect() - oldImageCount) + "张", Toast.LENGTH_LONG).show();
                return;

            }
        }

        if (isImage == false) {
            builder.onImageSelectedListener.onImageSelected(picData);
            dismiss();
        }

        if (builder != null && builder.isSingle) {
            // builder.onImageSelectedListener.onImageSelected(uri);
            builder.onImageSelectedListener.onImageSelected(picData);
            dismiss();
        }
    }

    private void startCameraIntent() {
        final Intent cameraInent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (cameraInent.resolveActivity(getActivity().getPackageManager()) == null) {
            errorMessage("This Application do not have Camera Application");
            return;
        }
        RxPermissions.getInstance(getActivity()).request(Manifest.permission.CAMERA).subscribe(new Subscriber<Boolean>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Boolean aBoolean) {
                if (aBoolean) {
                    File imageFile = getImageFile();
                    cameraInent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
                    startActivityForResult(cameraInent, REQ_CODE_CAMERA);
                } else {
                    new MaterialDialog.Builder(getActivity()).positiveText("同意")
                            .negativeText("取消").content(String.format(getString(R.string.no_permission), getString(R.string.app_name), "拍照"))
                            .positiveText("去设置").negativeText(null).onPositive(new MaterialDialog.SingleButtonCallback() {
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                            Uri packageURI = Uri.parse("package:" + getActivity().getPackageName());
                            //KLog.d(packageURI);
                            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                            startActivity(intent);
                        }
                    }).show();
                }
            }
        });
    }

    private void startGalleryIntent() {
        Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        if (galleryIntent.resolveActivity(getActivity().getPackageManager()) == null) {
            errorMessage("This Application do not have Gallery Application");
            return;
        }

        startActivityForResult(galleryIntent, REQ_CODE_GALLERY);

    }

    private File getImageFile() {
        // Create an image file name
        File imageFile = null;
        try {
            String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(new Date());
            String imageFileName = "JPEG_" + timeStamp + "_";
            File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);


            imageFile = File.createTempFile(
                    imageFileName,  /* prefix */
                    ".jpg",         /* suffix */
                    storageDir      /* directory */
            );


            // Save a file: path for use with ACTION_VIEW intents
            cameraImageUri = Uri.fromFile(imageFile);
        } catch (IOException e) {
            e.printStackTrace();
            errorMessage("Could not create imageFile for camera");
        }


        return imageFile;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            Uri selectedImageUri = null;
            if (requestCode == REQ_CODE_GALLERY && data != null) {
                selectedImageUri = data.getData();
                if (selectedImageUri == null) {
                    errorMessage();
                }
            } else if (requestCode == REQ_CODE_CAMERA) {
                // Do something with imagePath
                selectedImageUri = cameraImageUri;
                MediaScannerConnection.scanFile(getContext(), new String[]{selectedImageUri.getEncodedPath()}, new String[]{"image/jpeg"}, null);
            }

            if (selectedImageUri != null) {
                complete(selectedImageUri);
            } else {
                errorMessage();
            }
        }

    }

    private void errorMessage() {
        errorMessage(null);
    }

    private void errorMessage(String message) {
        String errorMessage = message == null ? "Something wrong." : message;

        if (builder != null && builder.onErrorListener == null) {
            Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_SHORT).show();
        } else {
            builder.onErrorListener.onError(errorMessage);
        }
    }


    public interface OnImageSelectedListener {
        void onImageSelected(List<Uri> uri);
    }

    public interface OnErrorListener {
        void onError(String message);
    }

    public interface ImageProvider {
        void onProvideImage(ImageView imageView, Uri imageUri);
    }

    public static class Builder {

        public Context context;
        public int maxCount = 25;
        public Drawable cameraTileDrawable;
        public Drawable galleryTileDrawable;

        public int spacing = 1;
        public OnImageSelectedListener onImageSelectedListener;
        public OnErrorListener onErrorListener;
        public ImageProvider imageProvider;
        public boolean showCamera = true;
        public boolean showGallery = true;
        public int peekHeight = -1;
        public int cameraTileBackgroundResId = R.color.tedbottompicker_camera;
        public int galleryTileBackgroundResId = R.color.tedbottompicker_gallery;

        public String title;
        public boolean showTitle = true;
        public int titleBackgroundResId;
        private boolean isSingle = false;
        private int maxSelect = Integer.MAX_VALUE;

        public Builder(@NonNull Context context) {

            this.context = context;

            setCameraTile(R.drawable.ic_camera);
            setGalleryTile(R.drawable.ic_gallery);
            setSpacingResId(R.dimen.tedbottompicker_grid_layout_margin);
        }

        public Builder setMaxCount(int maxCount) {
            this.maxCount = maxCount;
            return this;
        }

        public Builder setOnImageSelectedListener(OnImageSelectedListener onImageSelectedListener) {
            this.onImageSelectedListener = onImageSelectedListener;
            return this;
        }

        public boolean isSingle() {
            return isSingle;
        }

        public Builder setSingle(boolean single) {
            isSingle = single;
            return this;
        }

        public int getMaxSelect() {
            return maxSelect;
        }

        public Builder setMaxSelect(int maxSelect) {
            this.maxSelect = maxSelect;
            return this;
        }

        public Builder setOnErrorListener(OnErrorListener onErrorListener) {
            this.onErrorListener = onErrorListener;
            return this;
        }

        public Builder showCameraTile(boolean showCamera) {
            this.showCamera = showCamera;
            return this;
        }

        public Builder setCameraTile(@DrawableRes int cameraTileResId) {
            setCameraTile(ContextCompat.getDrawable(context, cameraTileResId));
            return this;
        }

        public Builder setCameraTile(Drawable cameraTileDrawable) {
            this.cameraTileDrawable = cameraTileDrawable;
            return this;
        }

        public Builder showGalleryTile(boolean showGallery) {
            this.showGallery = showGallery;
            return this;
        }

        public Builder setGalleryTile(@DrawableRes int galleryTileResId) {
            setGalleryTile(ContextCompat.getDrawable(context, galleryTileResId));
            return this;
        }

        public Builder setGalleryTile(Drawable galleryTileDrawable) {
            this.galleryTileDrawable = galleryTileDrawable;
            return this;
        }

        public Builder setSpacing(int spacing) {
            this.spacing = spacing;
            return this;
        }

        public Builder setSpacingResId(@DimenRes int dimenResId) {
            this.spacing = context.getResources().getDimensionPixelSize(dimenResId);
            return this;
        }

        public Builder setPeekHeight(int peekHeight) {
            this.peekHeight = peekHeight;
            return this;
        }

        public Builder setPeekHeightResId(@DimenRes int dimenResId) {
            this.peekHeight = context.getResources().getDimensionPixelSize(dimenResId);
            return this;
        }

        public Builder setCameraTileBackgroundResId(@ColorRes int colorResId) {
            this.cameraTileBackgroundResId = colorResId;
            return this;
        }

        public Builder setGalleryTileBackgroundResId(@ColorRes int colorResId) {
            this.galleryTileBackgroundResId = colorResId;
            return this;
        }

        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder setTitle(@StringRes int stringResId) {
            this.title = context.getResources().getString(stringResId);
            return this;
        }

        public Builder showTitle(boolean showTitle) {
            this.showTitle = showTitle;
            return this;
        }

        public Builder setTitleBackgroundResId(@ColorRes int colorResId) {
            this.titleBackgroundResId = colorResId;
            return this;
        }

        public Builder setImageProvider(ImageProvider imageProvider) {
            this.imageProvider = imageProvider;
            return this;
        }


        public TedBottomPicker create() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
                    && ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                throw new RuntimeException("Missing required WRITE_EXTERNAL_STORAGE permission. Did you remember to request it first?");
            }

            if (onImageSelectedListener == null) {
                throw new RuntimeException("You have to setOnImageSelectedListener() for receive selected Uri");
            }

            TedBottomPicker customBottomSheetDialogFragment = new TedBottomPicker();

            customBottomSheetDialogFragment.builder = this;
            return customBottomSheetDialogFragment;
        }


    }


}